{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Softmax Regression Example"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 生成数据集， 看明白即可无需填写代码\n",
    "#### '<font color=\"blue\">+</font>' 从高斯分布采样 (X, Y) ~ N(3, 6, 1, 1, 0).<br>\n",
    "#### '<font color=\"green\">o</font>' 从高斯分布采样  (X, Y) ~ N(6, 3, 1, 1, 0)<br>\n",
    "#### '<font color=\"red\">*</font>' 从高斯分布采样  (X, Y) ~ N(7, 7, 1, 1, 0)<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD8CAYAAABn919SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJztnX2UHlWd57+339LdAToQYnQTujtOwNccULsXhFnDEMeIIsOgcDbpYFzGyWHc1eC4cXVzODFhMuiOhxc9C574smaThuFlGIFFXOagsp5hBDoSzGB0yGgSQFEMmxaWHGKS3/5xu/JUV9fLrapbVbfq+X7OqfP083Q9dW9VJ9/61e/tKhEBIYSQ+tNR9QQIIYTYgYJOCCENgYJOCCENgYJOCCENgYJOCCENgYJOCCENgYJOCCENgYJOCCENgYJOCCENoStpB6XUNwBcBOA3IvLWqc9OAXA7gGEAewFcLiL/N+lYp556qgwPD+eYLiGEtB87duz4rYjMS9pPJZX+K6XeBeBlAP/TJ+j/DcCLIvJ5pdRnAJwsIv8labCRkRGZmJgwOgFCCCEapdQOERlJ2i/R5SIi/wfAi4GP/wTA1qmftwK4JPUMCSGEWCWrD32+iPwKAKZeXxO1o1JqjVJqQik18cILL2QcjhBCSBKFB0VFZIuIjIjIyLx5iS4gQgghGckq6L9WSr0OAKZef2NvSoQQQrKQVdDvBbB66ufVAO6xMx1CCCFZSRR0pdRtAP4JwBuUUs8qpf4MwOcB/LFS6mkAfzz1nhBCSIUk5qGLyIqIXy2zPBdCCCE5YKUoIYQ0BAo6ISSeyUngLW/Rr8RpKOiEkHjuvx/4yU+Ab3+76pmQBCjohJBwVq4ETjgBWD2V0PbhD+v3K1dWOy8SCQWdEBLOpk3A4CDQ3a3fd3cDQ0PAtddWOy8SCQWdEBLO4sVa1H//e2D2bP26cSPwB39Q9cxIBBR0Qkg0d9yhxXzjRv16551Vz4jEkJiHTghpY9atA778ZWD+fGDVKuCZZ6qeEYmBgk4IiWZ0tPXz/Pl6I85Clwsh7QbzyhsLBZ2QdoN55ZoG3tgo6IS0C8wrn04Db2wUdELaBeaVaxp8Y6OgE9IuMK9c0+AbGwWdkHaCeeWNvrFR0AlpJ9atA372M+BTn9Kv69ZVO5+qApMNvbExD52QdsK1vHJ/YHJF1Fo6BdDQgila6ISQ8qk6MDk62rqZzZ8PjIyUM27BUNAJIeXT4MBklVDQCSHl0+DAZJVQ0Akh1dDQwGSVUNAJaQfiskmqyjRxLeOmAVDQCWkH4srcqyqBb2hgskoo6IRURRmWcVw2SdWZJsQ6FHRCqqIMyzgum4SZJo2Dgk5I2ZRpGcdlk5hmmuR9kmhgm1pXoaATUjZlW8Zx2SQmmSZ5nyQa2KbWVZSIlDbYyMiITExMlDYeycb55+vX73+/ylk0nLvu0qXus2YBr74K3HYb8KEPFTPW44/rG8j8+cCvf63L3L0AZNzvVq4E7r1Xz+/IEaCrS8/34ouBW29NHjfv98lxlFI7RCQxakwLnZAqKDMHOy6bJO53eZ8kXPHRt5HLh4JOjnP++Xp7+GG9ee9JAdQhBztvNacr1aBt5PKhoBNSBS7mYIdZslmfJLxjjY9XVw3ahmmZbJ9LjuP5zMN86PSrtwFhrWyztpn1jrViBfCVr1TTpnbTJmDnTmDvXu3Db4O0TFrohLQ7cZZs2ieJ4LE2bgRe/3rgpJOApUuB008v7jyCuOLyKREKOpnB978/3VqnX73hbNoELFwIHD2q32e1ZCcnddbMwoXTA6Ennwy89JKOFYT5sYsMWrZZAzAKOiE2qHMmxeLFwPLlgIhOK8xqyd5/P7BnD/De9+pjdHUBhw4Bzz3X2mflSv25349dZNCyDsFnm4hIads73vEOIfVk6VK9kQjGx0UAkVtvrWb8gwdF3vxm/ZqGFStEZs8WUUrPv6NDvw4Opj9GV5f+rnesN72p9bO3KSWyeLHInj0zv9fVpd+vWJHuHNoAABNioLG5LHSl1CeVUk8ppf5ZKXWbUqrX0n2GkHrgSiZFVivXyxXv6dHvZ80CzjgDuOmm9Mfw3Cw9PfoY990HbNkCKNXat6MDuO46bf27kqeeRJ2evkxUP2wDsADALwD0Tb2/A8BH4r5DC52YUKungaef1pZoX5+2Mvv6tKW8Z08549uwcu+8s/W9ri79Pi1hx1ixQqSzc7qFHrT+bYxdNFU/fUlJFjp02mOfUqoLQD+AX+Y8HiH1oupMChtWro3AYdgxNm0CTjtNW/0A0Nur5+q3/tOMXbal7MrTVxpMVD9qA7AWwMsAXgAwHrHPGgATACYG0/jlSCK1smQN8M7HM+Rqc36XXSYyMCDyxS/q18svL3f8vFbuY4+JPP+8/vn550Uefzz9HKKOkTS3NGOXbSlX/fTlA4YWeh4xPxnAdwHMA9AN4FsAVsV9hy4Xu9RG8AypraDbEMQ8VH1DicPG3KoMnjriEjIV9MzdFpVSlwF4r4j82dT7DwM4R0Q+FvUddlu0g5cH/vDD+nXpUv3alCpOVqWmJK5jYtXYmNsTTwDnnAN0duo0yL4+YNEi3cmxaNfW5ZcDDz4IXHONdmMtXw7cfnuxY4Zg2m0xT+n/fgDnKKX6ARwCsAzatUIIKZPR0dbP8+e3KjvLZnISOPdc4JFHgIGB6XObnAQuuED/Li27dwOHD+sMmdmzdTvesuIUWVsfVERmQReRR5VSdwH4EYAjAJ4AsMXWxEg0cT1X0lCmJZxmrDTzqZU1HyZ4TcJLnXzLW4Cnnpp+jmF9YpJYuRK45x7glVf0+2PHdNBZKR08Lap/vB9XbpaG5MpyEZENIvJGEXmriFwhIq/amhipL2wPEEFRFZFV50kHs0Gee04LX96FqDdtAubMab3v7dVZRT/4QfMrPrNi4mi3tTEo6gZFBx/9xzMZK8v4tQqgFh3Ui8r+yFo9mpannxY56aSZ+eZ9fSIXXZQtU8S7Zl7lqredd17898o655JBSXnohBwnrJHXzp0VT8oFiqqITLJ+y1rYYfFi4K/+avpnPT06cHnjjdny9L1r5tHVpX3oJ50U/702WswiFBPVt7XRQneLoizzMKs5zjLPY2U7bZn7KSL9LSpP+qKLyk/zu+wykf7+lkWtVOscs6Yu3nmnrjTt79fn8NWvRqeE2noKctTCBy10UjZe292lS/Xmb8Nri9r654to4xpVpXrDDeX3SFm3Dli2DDjxRGDDBqC/v3WOWTse3nGHfuLYtEmf3z/8Q3TKY5oWwHExh7pb+Caqb2ujha5Ja1XWwQpNssZNv2tzX6coqvgoyvqtoiDG9jmmPd4nPqGt81mz4s85LObgeOdHFF0pmmUrW9Bd/c/fdEEv4rt53DN1uH6ZiRI9l6tHbWPaAjhOtB0q8w/DVNC5pmiJBCs8k3Ko0+5fBTbm6NL51I6oPOmaFcTkwls79Oc/10VHs2bppmBf+EL4fmFrjHrtfFesaBUv/e53wKmnVnJKWWmkoNdBCEk6shRTtfW/g9FR7SN+4xv1+0cfrXY+ReLFEvxivHkzcMklyfv5M268OMc11+jt2WfDi6QcppGC7ippRclWRWiR1GGObcv99+sgJJCuQtMV0lTW+sX42mujK0nj9lu3TgeWN2zQrQaAVpHUpZcCt95q9/yKwMQvY2ujD11DH3q5uDy3QohaWKKzU+SDH3QyLS+UNO1yTQOoSfvFFUn5A6QlpzeCQdFiKyDLHNc2Zc3PlevgyjxK4+mnRYaHpwuSt5bn9debi2RVVJ1x8qUvTb92PT0zA6Ql92Y3FfRG56EXkQfdjtQ293uKxvw7MO3ZsngxcPHFMz9/5hng05/WP7uy+k7YOVW91ugPfqDz6Dum5NFf3Rqszl25Urtwwq5jFT12TFTf1lbXPHTTlDnX+4tknV9WF5Gr16G2mFiFwRQ+v4V+4onupeVFnVOVC0s89pjIBz6g0z03bNBz8NI+g+mNgMiCBeHX0aIVD1roJImdO+N7rYT1ZsliqSeNQxJI07HQs257evT73l7gjDOAb3wDWL9+elVplWl5SedURGWtKaOjOmj6s58Bn/sc8K//2qpuXbwYOOUUvdCGx/PPA2ee2Zp7lWuRmqi+ra2uFrpH03zoSfPMa2mbjkMSSFv0EmXd+ouNvGPltR6zBgeTzilL1WlZgcoLL9TFS93dcjzY7J97AUVKYFDUPlUJuu3jDQzozVSos46fdhwSQxoXxGWX6UyN+fP1q+cueOwxkUsu0cfwsmA6O7U75oMfzDavPG4F226VogKVwRvFY4/pRmFdXbpxWGfnzLlbPjdTQafLJQWmwTXXg3BnnaW3poxTK7IGytK4INatAz7/eb2G5xe+0HIXjI4Cf/M3010yHR36fvuHf5huPjbcCv5z6u8HrrwyWwCxaBdHsGHX6KheZ3T2bO3iOuGEmX+PqlxGJqpva6u7hV42RQcXg8cryoLOe9xGWfZZrUhTF0Qw5S/MAr/zzplB07SpgWFuhTe8QadGmro8/Od0883ZreusLo4kF01c+qR/7v/yLyKLFk0/juVGZaCFTvx4AU3XUhBdm09h5LUiR0dbfVrmz49uI+tVO3ZNFYGHWeCe9fia17Q+S5saGNa6d/lyYM8e89azo6PAJz+pr8MnPqE/S7ouYU84UW2EkxbRSGqVG5c+6f97PP448ItftI4zOQl85CM6IA3E/71sY6L6tjZa6NmwYaHGBSirTDOMG6tR6Y9FdPMLszC9J4Dg1tXVstQ969Hz8/b16detW9MFFS+5RAcHlyyR46mRaa39tNcl6gknTXfJNIVLcb7wqOO8853WfflgULQ52GhNG/z/7T9mFcJpMmajBF2k2CBgUFyCW0+Pfr3hhtb3gyJ49tnphGjTJr3/9deLnH667kOe5WZlcl2SRDiNiyPNTSTuRhE8jufe8gLOFitcKegNI6uYmQh63jGykEasay/kHrZ6lIeJW1+fzmjxxKW3V2ThwnBfeX+/3ve739Xit2JFK1vDRIjCxp81S4+V5WblWfrXXht9XWw/4ZjeXJNuFP7jdHbqn3t77T2FTWEq6PSh56AO/l8v28bfrM77ucpMnDKWq3OOrEuxeXj+43XrZvp2Fy3SLWM9P/KRI3pJttmzgc7O1jG6u4GTT9ZFRc8/r/27mzZp37CX+ZLkTw/zLff0ZM/qePvbgWPHtM876rrE+cmzZA6ZZqEkxS78x+np0df98OF0vnybmKi+rc0VC92WxeeKa8LkGP588IEBdyzexljfZeB3sYRZmMEngHe/u5U9olRrJZ8wSzytOyi4/3XXaQv24EGRM84Q+d739H5xmSRpm3BFPeFkyRyylYXiz+33u7t6enThkaWVokCXSzS20ujK8O3mGaustERSMGHC19mpBcMvbn6RuuQS/ejvFxl/ZWPQJZDWHWQqrnFim9aNEhTh5cvdWAc0eB69vfo8fvhDa2vHUtBDsCXEVQYR83wnz80g65jEAmHCt2iRFgyR6L7eYSLz13+tBT1oiZtYrH5rO7j/e94zXVw9331S5kvQ0k+TaZPmhlB0WwD/eQD6PCxCQQ/BthC7kt4XtW9eNw0F3SGyZMiYuGXSuATSWNu9vdrtkJT5kjfTxvS6FN2/3DuPlSv1OGefbfXwFPQY6uRDz4INN03a7zYuxbBkEq9XFiEO+04W33GYy8fLlPFbvEFx/cu/TBZbbz5pM21Mr0uexTKirPqwz9/zHj1/f4WuRfcPBT2GdhGbPJZ52nTCJgq6U09gWYTYVuAvzLWxYMFMizcorgsXmt+EsqYlmiwplzXdMcqqD/u8iMIxHxR0YqUgKe0+TRByj7pkMZWCZ337uzQGLd6guH7zm+luKEUtapH2uFFW/dBQvLVf4KIcpoLOPPQGU1Rut62FL1yl6eeXCS/fet261tJswPSc9TPOAC64QOeDz5+v+9b09uoc8d7e+H4mk5O622J/v/0OhWk7H0b1cPn61+OXxqtyUQ4PE9W3tdXJQo+ylMpIUXSdpvc5r0sWU6n4re+vfjU8UybMFWEajPT2u+UW/d5Ch8LQuZseN8rajrPCLXdY9AO6XPJBQY/Gm6eN+bp8zmWkedr6fqkEF9AYHAzPk/dK4eOCkXmClkUSFWy11b4hJaaC3lX+M4HbeI/WDz88/b1H8PMsLo3gd6PGdK0UPjhPfzsBko/S/9aTk8C55wKPPJL+D7luHfBHfwR87GPALbdo98r69cDevbr0vbsbWLBAP+D88petzxYu1K1mvRL9c88Ftm/XC876v+t3Y5jMM8+5xJ3jl7+sz23VKuCZZ+I/dwQKOokl7uaSZzWiOtzETOZSh/MIxd8LfMUK8++tXAncey/w6qv6/cc/Dsyapf8xPP209h2/+ipw3XX69ytWtD5bvhz40pf0mCJ6/J/+VPus/fv5+5+YzDPrucQxOtr6ubdXxwMeeWT65/Pnt/q8uIKJGW9raxeXS9J3o3yzLj52F5XJEnctXLwOUdQmS8Ujr4sjKj3vwgtnuiI898RZZ8m0qtFg98ewNgYm8yzLXVN0UZIBKMPlopSaA+BrAN4KQABcKSL/ZOE+Qyrm/PP1k7D3dDxnjn49eNDO8YPuJuct2ghqdx6bNsW7OPyEuTK8rodBi3poSGeA+F0RIto98dJLwPveB+zfr/dXSh9LRI//2tcCt90GnH1267tz5iTPM825ZCH4NPLhDwN//ufAxRcDt95qZwzbmKh+1AZgK4CPTv3cA2BO3P51stCzYGqt2bLiig7QBjs0DgwUM04TipPqNNfc5fJZAoP+MTs6wrNkssyzwNzvoouF0oCi89CVUicBeBeAr0/dGA6LiCX7jVSJZ2161nlnp/55ctJ+TnZT+qDX6jyS8qWT1j/N0tfdP2ZHh96S8rVN8rrHx3Uv9c98xn7ud9a1SqvERPXDNgBnAXgMwDcBPAHtepkd952mW+geRVtreSzZNDEA7/heUSBzshtCkeXyJmM+8IDId74TPb7pPEVay+Ddeqv13G8RqSxNMQgMLXSl902PUmoEwA8BnCcijyqlbgLwOxG5JrDfGgBrAGBwcPAd+/bty3bnqRFF+1ODmRVLl5qPl2Zu/n3L9BHXxh/dZO66S/vJZ83SPuTbbgM+9KGqZ9XC798+cgTo6tJzte3ffvzxVmzg17/W/v24iteCUErtEJHEgfMI+msB/FBEhqfe/zsAnxGR90d9Z2RkRCYmJjKN5ypVik9acfYHOU1uAmGC7lGV2JqcM28IFrj8cuDBB4FrrtFBxuXLgdtvz39cWznje/Zo8d67Fzh0COjr08vw3Xuv2y6RjJgKemYfuog8D+AZpdQbpj5aBuAnWY9H3MPvF66Vj5jkJ+/6p1H4c8bzUEf/dhmY+GWiNmg/+gSAHwP4FoCT4/bP6kN30adq4sd2Zd7BuZqsKRqVI5/Gl26zHD5s/OB51DlLpvEUkTPuiH+7DFBGHrqI7ARQvkOpTaEroRx4nQugiJxxx8vwq8Dp0n+Xy6rjCkpcm3ea4pekuds4RhJx3/diAYB2x3rtbdPOkZRMVEFSHheJ62X4FcB+6DUgb39u//47d7K3dxTsg56P8V3jGL5xGB0bOzB84zDGd41P38GFfuENx2kLvQ4Wl4tziiIsWyVsHyD6mpucb96/W9z3w56EssyR2GV81zjW3LcGr/z+FQDAvsl9WHPfGgDA2JIxvVPQRbJ7t178wmaXxDbHaUEnmqwCGXRdzJnTSlvMeqwmi2UdDIhCWsVaYP1D64+Luccrv38F6x9a3xL0oIvkoYfsd0lsc2oh6E7+x4qhFsKQgI055z1G0vfreF1zU0SrWAvsn9xv/nkdm17VhMyFRVloYmFRHK4IepqKz6TFN9JUpRKLlFUZmZHhG4exb3JmFfhbe07Dru0nTn+iaLOiIBsUXlhEknGtGMefIWLjWAwYlkjUwsW2WsXmZPOyzejv7p/2WX93P76iPjCzkIhFQcVhkqxua2uX5lyuEldok3bxjToW7Wz/8XYZumFI1OeUDN0wJNt/vL3qKaXjzjt1pzSl9KvNVrEW8F/fb72tXw73zYouJLJRFHTwoG4advCg3RNxEHBNUeJhMy/etRx7U4yyMFznjjuAnh7tpujp0Wl/DjXMGlsy1rqWYz63SlghkY2iIEfjCVVClwsB0HIPLV2qt6C7yDX3UVrisjBqwcqVwH33afcEoF/vvbfVo9w1ktwqo6OtQqD589N1MEzq197G0EJvA2xm3dQ1gydVFoaLhJXOL1rkjA89FK+QyOvYaOuJouil52oMLXQHqTLgWHdLPIrBgcFUnztHHQOJRXVsrOO1KAkKehthU6yLFn7bN7WoLIzNyzbbG6Ro6lY6n8etkkTdrkVJ0OXiEElNqbyfSXq8YN36h9Zj/+R+DA4MYvOyzfUJiALsLuiH1yIUCjpxCpMsmribW9zvpmVh1BF2F2zBaxEKBT1AFZZwXPtXfwfAsH1JPmxfTyf+Po72eyHFQ0EnoVQlTFn7zNc1P74QmJ/dtlDQp6hCEEzGLDpNMOtx07pCXMP239uJGwqbXrU9FHQyDReEKanPeRU3vlrA/Oy2h4I+RZIgFCEUJu4F77O8lmPU+QSF2/R4/u/t3AmcdVa93B22bwBO3FCKWOaN1AoKOplGlcJk+nQQNyeXbyKlUFR1JqkFFPQAppZsEZa6zfGSjpNVuNM8VdQB23Ot/NyZn93WUNAbRBpBNV1btEyccFvUHeZntzUU9ATKFhlb45keJ6k4J43bo44CPL5rvN7VoxXB6+YmFHSHKMq9knXfqihrLo3okV4BvG7uQkE3pKoCmzKPExT7OXN00aH/dy4Jf16MVqonM8h13VjFWigUdAfIazWncdPQT92i9j3SU2DTRZLrurGKtVDYPpccJ7hq0cGD0SsYlcX4rnEM3ziMjo0dGL5xGOO7xq0du/Y90g3xXCT7JvdBIMddJFmvZabrxlWGSoGC7gBJy7+lPY7tfavCthAFaUSPdANsL7+X6bpt2gQMDurqVYBVrAVBQScz8It9lcJf9DqgY0vGsOUDWzA0MAQFhaGBIWz5wJbG+c9tu5YyXTeuMlQKSkRKG2xkZEQmJiZKG4/Um46NHRDM/PepoHBsw7EKZlRPhm8cxr7JfTM+HxoYwt6r95Y3kcsvBx58sFXFunw5cPvt5Y1fY5RSO0QkccknWugkkarWOG0XH3fROONaKmqNUXIcCjqJpCoh98Z1RogsUERw1/SYzriWilxjlACgy4XEMGeOfvVy0Zcu1a9F+9T9KZVFVSSWWekYLMQBtNvoqpGrcPP7b7Z2zP7u/kbGAIi5y4WCTmYQzIv3KFrQg+MWNV7ZYhjlw1ZQ2HbptkxjOuMXJ6VAHzqxxsCA3pIyXqpy0XiYuiCKzp4JEpVNIpDMY7ZTURQxJ3elqFKqE8AEgOdE5KL8UyJVE6wmrWrcNJZ5mv4iZYvh4MBgqDWdZ8yoY7oQMGbjruqwYaGvBbDbwnGIo5ha5g8/rLcqLPU0VnfZ2TObl22GgrI6ZtUB46inoaKLwUg8uQRdKbUQwPsBfM3OdIhLVFVUlGXcNFZ32WI4tmQMV41cNUPUTccME88qM1fiRLtsdxaZTl6Xy40APg3gRAtzITWl7IZfYeOkcUF4oleGW8Dvfjil7xQAwIuHXjQeM8mVVIUrI0606duvlsyCrpS6CMBvRGSHUur8mP3WAFgDAIOD1fv3SDPZvGxzaOZKlAVchhgGxfjAoQPo7+5Pldmy9oG1zrX4jRNtl3377UAel8t5AC5WSu0F8LcALlBKbQ/uJCJbRGREREbmzZuXYzjiOkW7aOJ89c4Uz/jI634Y3zWOA4cOhP7OE9U4X3YVXSqr9u23O5ktdBH5LIDPAsCUhf6fRWSVpXkRkpqqXBBR5HU/xAn/4MBgpDvmH/f/I7Y+ubWwFYXinobKdGeRmVgpLPIJemzaIguLiA3qsjhH3uKfqOZkALD90u1Y/9D6yIKlsO/ZLDpiamK5lFpYJCLfZw56eVRdwEPMyOt+iPM7R4k5gMibgM3A5NiSMey9ei+ObTiGvVfvjRTzIl0/ZCasFCW1o2hfvS0RyuPXH981jpcPvxz5+32T+yJz26MoOzDJnPTy4ZqiNSLv2qMkmbwr2oe5IqLcHFFui7BeM2EIJNK9EkbZgUkuwl0+tNAJ8ZEnMyWNRZq2OCcKUzGf2zd3mogW7QoZ3zVuvd0BSYYWeo0ou4CnHcmTmZLGIs1SnJOV/u5+3HThTcffj+8ax5X3XInDRw8D0E8hV95zJYD8WTDju8ax9oG1kemWAHPSi4QWOiE+8vR5SXMzSCrOCSPoMzfxofv99p5VvuruVcfF3OPw0cNY+8DaxOPF4T11xIk5c9KLhYJeQ6pcuLnp5MlMSXMziNr3lL5TIoOhs3tmY27f3OMB1iR3i4I6noHid/FEESfEJpi4iqou9mo6FHRCfOTJTElzMwjbF9CiGiWsLx9+GYeOHMK2S7dh79V7MTQwFDsf/00jjV8+K0muoqGBIYp5wVDQCQlgmmMd9j3Tm4G379y+uanm5g/QRt0UgNaNxHOzxFnmHmnnEiTOLeWiq6WJOfIUdFJbXPwPGXczCM4XAE7oOSH1GPsm96FjYwfWP7Qeq89cfdxS71SdAFp+cwCJbpYgea5h1A1mbt9c51wtTc2R55qipJYUsfBykUStY5rXDRK3FqqpZW56PBPq0hKgbmuycpFo0miKWHi5SKLm26k6cVSO5jp2lAjF9YIZGhjCy4dfDvXXm4haXYQ7iqhro6BwbMOxCmYUDxeJJo0mz8LLRbacjTpGlKV8VI7OcFN46YhDA0P4i5G/OO6TjyKqla63oEYQT7BfPPRi7PHizrHu7oqylyEsCxYWkVqSdeHlIlvOxh07rgPi5mWbjazdKCs/qpVuGP7gZNbFKJpQ0p92QZS6QAud1JKsCy9HidGWHVtyr4UZd+yox3tPvE2yauLSIk3SEoPByaw5901YZs7FBVFsQEEntSTrwstRohPlx04jUmmPLZBUAjK2ZAyrz1x9PJulU3Vi9ZmrMbZkzGieJ/ScMG28rKLWFHdF1vRUl6Ggk9py8/t0e4ELAAAKuUlEQVRvxrZLt00TpNVnrsb6h9ZH+sGjRMcTySAdqsPYN5z22J2qM5XfeXzXOLY+ufX4DeKoHMXWJ7difNd4rtYEaeEyc+5CQSe1xm9lbV62GVuf3BobrIsSozXvWBOaQ31UjhoH/Io8NhDvu44rMvIIin7W4GZT3RVNgGmLpDEk5RZ7qXb7JvcdTxf0gpJev5PVf7861EVimp8c1+M877GTUu385xcMwobll9ctF7udYR46aTviBG/bpdtCsxqCIldkfnJSXnjWLJcwATbJE1cbw4PKruZitzPMQydtR1ywznThiqjc7ajPbcxPQRm5PdL4rpMCfuO7xjNlCdUBF1tClAUFnTSGOMFzIdUubH5h+elR6ZI2fdfrH1ofm0ppi7LFtQlFT3mgy4U0iihXg6m7ouiS8OD8ogqAinZ7xLl/ZIMdTYjqX1NkALWpcQG6XEhbEuVqMHVX2MixjrNKg/OL6mmeNF5eyzfO/WPDmvWCwHmLtdLiwpNYlVDQSVtg6q7Im2Od9pE/zXieiKuNClfcfUUut0JUpa1JL5wkvGtgo1grLU0pesoKXS6EBMjTSTDLI7/JeGHuizRjhFFUlktS294i3R9VuHnKgGmLhFRAnG96+6XbM4uKaW9zBWV8E7LlbzaNCwDliGvdW/uGYSro7LZIiEXiBC1t90Y/pm4KvwsmaSwbHQfDujxGdZbsVJ2lWMpjS8ZqL+BZoQ+dEIvEleDnCQim9QFHjeUPpvqXsMuaBhmW3y+Q0KZpW/90a9sKbVnQQifEIp5grbp7VejvswYEw6zpKEs4aqwwa3rrk1tzWc1xC42YVL8Su9BCJ8QyY0vGMqcjxh0zmKWz7dJtkA1iPJZptWwaos7H88M3qTVtHaCgExJBnlzvIlrMpsmx7+7oxsuHX5429ywrPAUJXpP3nf6+QlvptnMZfxYo6ISEkLeEvKgWs2ECFxxrbt9cKKVw4NCB43O/8p4rI49p+tQQdk22Prk1tx8+zXjtVMafBaYtEhKCiyXkSTnW/va5pnidKE0EuOxr4uLfoCqYtkhIDlwsIU/ygScVHoWRZhm8sq+Ji38D16HLhZAQXCwhjxM4k0Wiw4gKqAIz3TtRLYSLuiYu/g1ch4JOSAgurpsZJ3BJVmtXRxe6O7qnfRZ3PmH+65cOv5T6GHkCmi7+DVwns6ArpU5TSn1PKbVbKfWUUmqtzYkRUiVpgpplZWLECVyS1aqg8NG3f9Q4eBlm8R8+ehgnzTrJ6Bgfu/9juRuIce3S9GQOiiqlXgfgdSLyI6XUiQB2ALhERH4S9R0GRUnTCAtUegU//vVKbY4XtWapzeZdefrCj+8axxV3XxH6/XYMaNqg8KCoiPwKwK+mfn5JKbUbwAIAkYJOSNOIKn0HYNxTJQ3BPiXe08H+yf04pe8U9HX14cChA6HfTRNMjOpJY+K/jloNKe0cSHqs+NCVUsMA3gbgURvHI6QuJAlU1kpMEzdO0M994NABHDpyCHP75oYeM00wMY//Ou6aMKBZLLkFXSl1AoC/A3C1iPwu5PdrlFITSqmJF154Ie9whDiFiUCltUpNC2qi0hgB5A4m5vFfx62GxIBmseQSdKVUN7SYj4vI3WH7iMgWERkRkZF58+blGY4Q54jrruiR1io17bkSdaM4cOhAJjEOPhUAyNSPJWox7KtGrmJAs2Ay+9CVUgrA1wHsFpHr7U2JkPrgCZRXoRnsgJglzc60oCbKz+21rk27SEWwE2NW/7//mrDbYrnksdDPA3AFgAuUUjuntvdZmhchtcFrmiUbBNsu3ZY7zc60oMbmuqC2OzGOLRk7nk7pFT6xB0vxsJcLIY6RZl1MW+uC5klTDKOpa3tWhWnaIitFCXGMNAHJPH3X/T7zDhUuBVmzUqIs/tV/v5qWeoGwORchDmK6LmbWdUGDFvRROTpjnzxl9lFxgKNy1HpuPmlBC52QGpM1vTCqmVen6rRSZh9n2ReZm9/u0IdOSAlElezn3Tcrtn3mQZJaEaQdp9198vShE+IIaVbeKWuVnqJb03pPDp2q08o4RayH2kQo6IQUTBoxWvvA2lKEq4zWtGNLxrD1T7daGYeLXZhBQSekYEzFaHzXuJXGWiaU1ZrW1jhc7MIMCjohBWMqRnFWeJxwZQ0WegVRYaX9NgOQceOYngsXuzCDaYuEFIxpamGcFZ60spCNkn3veGsfWDvtSaGINsBRYyedC9sJxMMsF0JKwCRzJWqV+7l9c/HbT/829LhR38mykERSZkrRi1PYPJemUfgCF4QQc0wKhaIs+ZsuvCnyOzaDhUkLTRcdgGTgMz/0oRPiCFkCiDaDhUnCWXQAkoHP/FDQCXGINAFEwG6wME44ywhAMvCZHwo6ISHUpczcZvph1GIdc/vmllKRWVYqZZNhUJSQAK6UmZfRAsCFMUkypkFRCjohAVzItnDlpkLcgL1cCMmIC9kW7F1CskBBJySAC9kWLtxUSP2goBMSwIVsCxduKqR+UNAJCeBCtoULNxVSPxgUJcRRmHFCPJjlQgghDYFZLoQQ0mZQ0AkhpCFQ0AkhpCFQ0AkhpCFQ0AkhpCFQ0AkhpCFQ0AkhpCGUmoeulHoBwMw2di1OBRC+eGJ7w+sSDq/LTHhNwqn7dRkSkXlJO5Uq6EkopSZMkufbDV6XcHhdZsJrEk67XBe6XAghpCFQ0AkhpCG4Juhbqp6Ao/C6hMPrMhNek3Da4ro45UMnhBCSHdcsdEIIIRlxQtCVUu9VSv1MKbVHKfWZqufjAkqp05RS31NK7VZKPaWUWlv1nFxCKdWplHpCKfW/qp6LKyil5iil7lJK/XTq3807q56TCyilPjn1f+iflVK3KaV6q55TUVQu6EqpTgD/HcCFAN4MYIVS6s3VzsoJjgD4lIi8CcA5AP4jr8s01gLYXfUkHOMmAN8RkTcCOBO8PlBKLQDwCQAjIvJWAJ0A/n21syqOygUdwL8FsEdEfi4ihwH8LYA/qXhOlSMivxKRH039/BL0f84F1c7KDZRSCwG8H8DXqp6LKyilTgLwLgBfBwAROSwiB6udlTN0AehTSnUB6Afwy4rnUxguCPoCAM/43j8LCtc0lFLDAN4G4NFqZ+IMNwL4NIBjVU/EIV4P4AUA/2PKFfU1pdTsqidVNSLyHIAvAtgP4FcAJkXkwWpnVRwuCLoK+YypN1MopU4A8HcArhaR31U9n6pRSl0E4DcisqPquThGF4C3A7hFRN4G4P8BaPt4lFLqZOgn/kUA/g2A2UqpVdXOqjhcEPRnAZzme78QDX4kSoNSqhtazMdF5O6q5+MI5wG4WCm1F9o9d4FSanu1U3KCZwE8KyLeU9xd0ALf7rwbwC9E5AUR+T2AuwGcW/GcCsMFQX8cwOlKqUVKqR7ogMW9Fc+pcpRSCtofultErq96Pq4gIp8VkYUiMgz9b+W7ItJYi8sUEXkewDNKqTdMfbQMwE8qnJIr7AdwjlKqf+r/1DI0OFjcVfUEROSIUuo/Afjf0BHob4jIUxVPywXOA3AFgF1KqZ1Tn/1XEfl2hXMibvNxAONThtHPAfyHiudTOSLyqFLqLgA/gs4cewINrhplpSghhDQEF1wuhBBCLEBBJ4SQhkBBJ4SQhkBBJ4SQhkBBJ4SQhkBBJ4SQhkBBJ4SQhkBBJ4SQhvD/AWZ6uqmdyT6QAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from matplotlib import animation, rc\n",
    "from IPython.display import HTML\n",
    "import matplotlib.cm as cm\n",
    "import numpy as np\n",
    "%matplotlib inline\n",
    "\n",
    "dot_num = 100\n",
    "x_p = np.random.normal(3., 1, dot_num)\n",
    "y_p = np.random.normal(6., 1, dot_num)\n",
    "y = np.ones(dot_num)\n",
    "C1 = np.array([x_p, y_p, y]).T\n",
    "\n",
    "x_n = np.random.normal(6., 1, dot_num)\n",
    "y_n = np.random.normal(3., 1, dot_num)\n",
    "y = np.zeros(dot_num)\n",
    "C2 = np.array([x_n, y_n, y]).T\n",
    "\n",
    "x_b = np.random.normal(7., 1, dot_num)\n",
    "y_b = np.random.normal(7., 1, dot_num)\n",
    "y = np.ones(dot_num)*2\n",
    "C3 = np.array([x_b, y_b, y]).T\n",
    "\n",
    "plt.scatter(C1[:, 0], C1[:, 1], c='b', marker='+')\n",
    "plt.scatter(C2[:, 0], C2[:, 1], c='g', marker='o')\n",
    "plt.scatter(C3[:, 0], C3[:, 1], c='r', marker='*')\n",
    "\n",
    "data_set = np.concatenate((C1, C2, C3), axis=0)\n",
    "np.random.shuffle(data_set)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建立模型\n",
    "建立模型类，定义loss函数，定义一步梯度下降过程函数\n",
    "\n",
    "填空一：在`__init__`构造函数中建立模型所需的参数\n",
    "\n",
    "填空二：实现softmax的交叉熵损失函数(不使用tf内置的loss 函数)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'tf' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-1-dac53f086976>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mepsilon\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1e-12\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mclass\u001b[0m \u001b[0mSoftmaxRegression\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m         \u001b[0;34m'''============================='''\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m         \u001b[0;31m#todo 填空一\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-1-dac53f086976>\u001b[0m in \u001b[0;36mSoftmaxRegression\u001b[0;34m()\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrainable_variables\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mW\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m     \u001b[0;34m@\u001b[0m\u001b[0mtf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunction\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     10\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     11\u001b[0m         \u001b[0mlogits\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatmul\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mW\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mb\u001b[0m \u001b[0;31m# shape(N, 3)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'tf' is not defined"
     ]
    }
   ],
   "source": [
    "epsilon = 1e-12\n",
    "class SoftmaxRegression():\n",
    "    def __init__(self):\n",
    "        '''============================='''\n",
    "        #todo 填空一，构建模型所需的参数 self.W, self.b 可以参考logistic-regression-exercise\n",
    "        '''============================='''\n",
    "        \n",
    "        self.trainable_variables = [self.W, self.b]\n",
    "    @tf.function\n",
    "    def __call__(self, inp):\n",
    "        logits = tf.matmul(inp, self.W) + self.b # shape(N, 3)\n",
    "        pred = tf.nn.softmax(logits)\n",
    "        return pred    \n",
    "    \n",
    "@tf.function\n",
    "def compute_loss(pred, label):\n",
    "    label = tf.one_hot(tf.cast(label, dtype=tf.int32), dtype=tf.float32, depth=3)\n",
    "    '''============================='''\n",
    "    #输入label shape(N, 3), pred shape(N, 3)\n",
    "    #输出 losses shape(N,) 每一个样本一个loss\n",
    "    #todo 填空二，实现softmax的交叉熵损失函数(不使用tf内置的loss 函数)\n",
    "    '''============================='''\n",
    "    loss = tf.reduce_mean(losses)\n",
    "    \n",
    "    accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(label,axis=1), tf.argmax(pred, axis=1)), dtype=tf.float32))\n",
    "    return loss, accuracy\n",
    "\n",
    "@tf.function\n",
    "def train_one_step(model, optimizer, x, y):\n",
    "    with tf.GradientTape() as tape:\n",
    "        pred = model(x)\n",
    "        loss, accuracy = compute_loss(pred, y)\n",
    "        \n",
    "    grads = tape.gradient(loss, model.trainable_variables)\n",
    "    optimizer.apply_gradients(zip(grads, model.trainable_variables))\n",
    "    return loss, accuracy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实例化一个模型，进行训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss: 0.7527\t accuracy: 0.8067\n",
      "loss: 0.6212\t accuracy: 0.8667\n",
      "loss: 0.5481\t accuracy: 0.8933\n",
      "loss: 0.5002\t accuracy: 0.8933\n",
      "loss: 0.4658\t accuracy: 0.8933\n",
      "loss: 0.4396\t accuracy: 0.89\n",
      "loss: 0.4188\t accuracy: 0.8967\n",
      "loss: 0.4018\t accuracy: 0.8933\n",
      "loss: 0.3876\t accuracy: 0.8933\n",
      "loss: 0.3755\t accuracy: 0.8967\n",
      "loss: 0.3649\t accuracy: 0.8967\n",
      "loss: 0.3557\t accuracy: 0.9\n",
      "loss: 0.3476\t accuracy: 0.9\n",
      "loss: 0.3403\t accuracy: 0.9\n",
      "loss: 0.3337\t accuracy: 0.9\n",
      "loss: 0.3277\t accuracy: 0.9\n",
      "loss: 0.3223\t accuracy: 0.9067\n",
      "loss: 0.3173\t accuracy: 0.9067\n",
      "loss: 0.3127\t accuracy: 0.91\n",
      "loss: 0.3084\t accuracy: 0.91\n"
     ]
    }
   ],
   "source": [
    "model = SoftmaxRegression()\n",
    "opt = tf.keras.optimizers.SGD(learning_rate=0.01)\n",
    "x1, x2, y = list(zip(*data_set))\n",
    "x = list(zip(x1, x2))\n",
    "for i in range(1000):\n",
    "    loss, accuracy = train_one_step(model, opt, x, y)\n",
    "    if i%50==49:\n",
    "        print(f'loss: {loss.numpy():.4}\\t accuracy: {accuracy.numpy():.4}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 结果展示，无需填写代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10000, 2)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(C1[:, 0], C1[:, 1], c='b', marker='+')\n",
    "plt.scatter(C2[:, 0], C2[:, 1], c='g', marker='o')\n",
    "plt.scatter(C3[:, 0], C3[:, 1], c='r', marker='*')\n",
    "\n",
    "x = np.arange(0., 10., 0.1)\n",
    "y = np.arange(0., 10., 0.1)\n",
    "\n",
    "X, Y = np.meshgrid(x, y)\n",
    "inp = np.array(list(zip(X.reshape(-1), Y.reshape(-1))), dtype=np.float32)\n",
    "print(inp.shape)\n",
    "Z = model(inp)\n",
    "Z = np.argmax(Z, axis=1)\n",
    "Z = Z.reshape(X.shape)\n",
    "plt.contour(X,Y,Z)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
